#pragma once
//#include "stdafx.h"
#include "Vector.h"
#include <stdio.h>      /* printf, NULL */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */
namespace org
{
	namespace spark
	{
		namespace math
		{

			/*Vector::Vector(Vector v)
			{
				this->x = v.x;
				this->y = v.y;
				this->z = v.z;
			}*/

			Vector::Vector(double x, double y, double z)
			{
				this->x = x;
				this->y = y;
				this->z = z;
			}

			Vector::Vector(double v)
			{
				this->x = this->y = this->z = v;
			}

			/*Vector::Vector(java::awt::Color *color)
			{
				set_Renamed(color);
			}*/

			Vector::Vector()
			{
				this->x = this->y = this->z = 0;
			}

			Vector Vector::set_Renamed(Vector v)
			{
				x = v.x;
				y = v.y;
				z = v.z;

				return *this;
			}

			/*Vector Vector::set_Renamed(java::awt::Color *color)
			{
				this->x = color->getRed() / 255.0;
				this->y = color->getGreen() / 255.0;
				this->z = color->getBlue() / 255.0;

				return *this;
			}*/

			Vector Vector::set_Renamed(double x, double y)
			{
				this->x = x;
				this->y = y;

				return *this;
			}

			Vector Vector::set_Renamed(double x, double y, double z)
			{
				this->x = x;
				this->y = y;
				this->z = z;

				return *this;
			}

			Vector Vector::set_Renamed(double v)
			{
				x = y = z = v;

				return *this;
			}

			Vector Vector::add(Vector v)
			{
				x += v.x;
				y += v.y;
				z += v.z;

				return *this;
			}

			Vector Vector::add(Vector v, double a)
			{
				x += v.x * a;
				y += v.y * a;
				z += v.z * a;

				return *this;
			}

			Vector Vector::sub(Vector v)
			{
				x -= v.x;
				y -= v.y;
				z -= v.z;

				return *this;
			}

			Vector Vector::mul(double v)
			{
				x *= v;
				y *= v;
				z *= v;

				return *this;
			}

			Vector Vector::div(double v)
			{
				x /= v;
				y /= v;
				z /= v;

				return *this;
			}

			Vector Vector::negate()
			{
				x = -x;
				y = -y;
				z = -z;

				return *this;
			}

			double Vector::dot(Vector v)
			{
				return x*v.x + y*v.y + z*v.z;
			}

			Vector Vector::cross(Vector v)
			{
				double xx, yy, zz;

				xx = y * v.z - z * v.y;
				yy = z * v.x - x * v.z;
				zz = x * v.y - y * v.x;

				x = xx;
				y = yy;
				z = zz;

				return *this;
			}

			/*Vector Vector::parallelComponent(Vector unitBasis)
			{
				double projection = dot(unitBasis);
				return (Vector(unitBasis))->mul(projection);
			}

			Vector Vector::perpendicularComponent(Vector unitBasis)
			{
				return parallelComponent(unitBasis).negate()->add(this);
			}*/

			double Vector::length()
			{
				return sqrt(x*x + y*y + z*z);
			}

			double Vector::norm2()
			{
				return x*x + y*y + z*z;
			}

			double Vector::lengthSquared()
			{
				return x*x + y*y + z*z;
			}

			Vector Vector::normalize()
			{
				double l = length();
				if (abs(l) < 1e-10)
				{
					x = 0;
					y = 0;
					z = 0;
				}
				else
				{
					l = 1 / l;
					x *= l;
					y *= l;
					z *= l;
				}

				return *this;
			}

			Vector Vector::truncate(double min, double max)
			{
				if (x < min)
					x = min;
				else if (x > max)
					x = max;

				if (y < min)
					y = min;
				else if (y > max)
					y = max;

				if (z < min)
					z = min;
				else if (z > max)
					z = max;

				return *this;
			}

			Vector Vector::truncateDistance(double max)
			{
				double d = x*x + y*y + z*z;

				if (d > max*max)
				{
					d = max / sqrt(d);
					x *= d;
					y *= d;
					z *= d;
				}

				return *this;
			}

			Vector Vector::truncateLength(double max)
			{
				double d = x*x + y*y + z*z;

				if (d > max*max)
				{
					d = max / sqrt(d);
					x *= d;
					y *= d;
					z *= d;
				}

				return *this;
			}

			/*std::string Vector::ToString()
			{
				return x + ";" + y + ";" + z;
			}*/

			/*java::awt::Color *Vector::toAWTColor()
			{
				float r = static_cast<float>(x);
				float g = static_cast<float>(y);
				float b = static_cast<float>(z);

				if (r < 0)
					r = 0;
				else if (r > 1)
					r = 1;

				if (g < 0)
					g = 0;
				else if (g > 1)
					g = 1;

				if (b < 0)
					b = 0;
				else if (b > 1)
					b = 1;

				return new java::awt::Color(r, g, b);
			}

			java::awt::Color *Vector::toAWTColorInt()
			{
				return new java::awt::Color(static_cast<int>(x), static_cast<int>(y), static_cast<int>(z));
			}*/

			Vector Vector::getVector(double length, double dir)
			{
				dir *= M_PI / 180;
				Vector *v=new Vector(length * cos(dir), length * sin(dir), 0);
				return *v;
			}

			Vector Vector::randomVector(double min, double max)
			{
				
				
				double x = fRand(min, max);
				double y = fRand(min, max);
				double z = fRand(min, max);

				return Vector(x, y, z);
			}

			Vector Vector::randomVector2d(double min, double max)
			{
				double x = fRand(min, max);
				double y = fRand(min, max);
				double z = 0;

				return Vector(x, y, z);
			}

			Vector Vector::randomVector(double radius)
			{
				return randomUnitVector().mul(rand() * radius);
			}

			Vector Vector::randomVector2d(double radius)
			{
				return randomUnitVector2d().mul(rand() * radius);
			}

			Vector Vector::randomUnitVector()
			{
				return randomVector(-1, 1).normalize();
			}

			Vector Vector::randomUnitVector2d()
			{
				return randomVector2d(-1, 1).normalize();
			}

			/*Vector Vector::parseVector(const std::string &str)
			{
				double x, y, z;

//ORIGINAL LINE: String[] vals = str.split(";", 3);
// WARNING: Since the array size is not known in this declaration, converted this array to a pointer.   call 'delete[]' where appropriate:
// There is no direct native C++ equivalent to the Java String 'split' method:
				std::string *vals = str.split(";", 3);
				if (vals->length < 3)
					return Vector();

				x = StringConverterHelper::fromString<double>(vals[0]);
				y = StringConverterHelper::fromString<double>(vals[1]);
				z = StringConverterHelper::fromString<double>(vals[2]);

				return Vector(x, y, z);
			}*/

			/*Vector Vector::fromAWTColor(java::awt::Color *color)
			{
				double x, y, z;

				x = color->getRed() / 255.0;
				y = color->getGreen() / 255.0;
				z = color->getBlue() / 255.0;

				return Vector(x, y, z);
			}*/

			double Vector::distance(Vector v1, Vector v2)
			{
				double x = v1.x - v2.x;
				double y = v1.y - v2.y;
				double z = v1.z - v2.z;

				return sqrt(x*x + y*y + z*z);
			}
			double fRand(double fMin, double fMax)
			{
				double f = (double)rand() / 1+RAND_MAX;
				return fMin + f * (fMax - fMin);
			}


			/*bool Vector::Equals(Vector *v)
			{
				if (v == this)
					return true;

				if (dynamic_cast<Vector>(v) != 0)
				{
					Vector vv = static_cast<Vector>(v);
					return vv.x == x && vv.y == y && vv.z == z;
				}

				if (dynamic_cast<Vector4d*>(v) != 0)
				{
					Vector4d *vv = static_cast<Vector4d*>(v);
					return vv->a == 0 && vv->x == x && vv->y == y && vv->z == z;
				}

				return false;
			}*/
		}
	}
}
